#include <stdio.h>
#include <string.h>
#include <math.h>
#include <ctype.h>
#include <stdlib.h>
#define ll long long
#define maxn 100+5
#pragma GCC optimize(2)
const double eps=1e-11;
ll read(){
   char c=getchar();
   ll Suzumiya=1LL,Haruhi=0LL;
   while(c<'0' || c>'9'){
      if(c=='-')
         Suzumiya=-1LL;
      c=getchar();
   }
   while(c>='0' && c<='9'){
      Haruhi=Haruhi*10+(c-'0');
      c=getchar();
   }
   return Suzumiya*Haruhi;
}

void printMartix(double a[][105],int N);
void lineSwap(double a[][105],int m,int n,int N);//互换第m行和第n行
void lineMult(double a[][105],int n,double k,int N);//将第n行乘以k
void linePlus(double a[][105],int m,int n,double k,int N);//将第m行乘以k以后加到第n行
int gauss(double a[][105],int N);//化为阶梯型矩阵
void solveX(double x[],double a[][105],int n);
double Abs(double x);

inline double Abs(double x){
    return x<0.0?-1.0*x:x;
}

int main(){
    int n;
    double a[maxn][maxn];
    double x[maxn];

    printf("请输入矩阵的阶数n,n<=100:");
    n=read();
    printf("请输入%d行%d列的增广矩阵:\n",n,n+1);
    for(int i=1;i<=n;++i)
        for(int j=1;j<=n+1;++j)
            scanf("%lf",&a[i][j]);
    if(gauss(a,n)){
        printf("计算成功，行化简后矩阵为：\n");
        printMartix(a,n);
        solveX(x,a,n);
        printf("方程组的解为：\n");
        for(int i=1;i<=n;++i)
            printf("x%d=%10.5lf\n",i,x[i]);
    } else
        printf("ERROR!!\n");
    return 0;
}

inline int gauss(double a[][105],int N){
    for(int i=1;i<=N;++i){//i:当前正在做第i行
        double mainElement=a[i][i];//主元
        if(Abs(mainElement)<=eps)//a[i][i]==0
            return 0;
        
        for(int j=i+1;j<=N;++j){
            double k=a[j][i]/mainElement;
            linePlus(a,i,j,-k,N+1);
        }
        //printMartix(a,N);
    }
    return 1;
}

inline void linePlus(double a[][105],int m,int n,double k,int N){
    for(int i=1;i<=N;++i)
        a[n][i]+=a[m][i]*k;
}

inline void lineSwap(double a[][105],int m,int n,int N){//互换第m行和第n行
    for(int i=1;i<=N;++i){
        //swap(a[m][i],a[n][i]);
        double temp=a[m][i];
        a[m][i]=a[n][i];
        a[n][i]=temp;
    }
}

inline void lineMult(double a[][105],int n,double k,int N){
    for(int i=1;i<=N;++i){
        a[n][i]*=k;
    }
}//将第n行乘以k

inline void printMartix(double a[][105],int N){
    for(int i=1;i<=N;++i){
        for(int j=1;j<=N+1;++j)
            printf("%10.6lf ",a[i][j]);
        printf("\n");
    }
}

inline void solveX(double x[],double a[][105],int n){
    x[n]=a[n][n+1]/a[n][n];
    for(int i=n-1;i>=1;--i){
        double temp=0.0;
        for(int j=i+1;j<=n;++j){
            temp+=a[i][j]*x[j];
        }
        temp=a[i][n+1]-temp;
        //printf("i=%d,temp=%lf\n",i,temp);
        x[i]=temp/a[i][i];
    }
}